# ========================== 导入模块 ==========================
import sys
import json
import socket
import threading
import os
from PyQt5.QtWidgets import (QApplication, QMainWindow, QDialog, QLabel, QPushButton,
                             QVBoxLayout, QHBoxLayout, QWidget, QLineEdit, QMessageBox,
                             QListWidget, QTextBrowser, QListWidgetItem, QAbstractItemView, QTextEdit, QToolButton,
                             QSpacerItem, QSizePolicy, QInputDialog, QFileDialog)
from PyQt5.QtGui import QPixmap, QIcon, QFont, QPainter
from PyQt5.QtCore import Qt, pyqtSignal, QObject, QSize, QFile


# ========================== 基础组件 ==========================
class SidebarButton(QToolButton):
    def __init__(self, icon_path, text="", parent=None, is_avatar=False):
        super().__init__(parent)
        self.setFixedSize(70, 70)
        self.setToolButtonStyle(Qt.ToolButtonIconOnly)

        if is_avatar:
            pixmap = QPixmap(icon_path).scaled(60, 60, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation)
            mask = QPixmap(60, 60)
            mask.fill(Qt.transparent)
            painter = QPainter(mask)
            painter.setRenderHint(QPainter.Antialiasing)
            painter.setBrush(Qt.black)
            painter.drawEllipse(0, 0, 60, 60)
            painter.end()
            pixmap = pixmap.copy(mask.rect())
            pixmap.setMask(mask.mask())
            self.setIcon(QIcon(pixmap))
            self.setIconSize(QSize(60, 60))
            self.setStyleSheet("""
                QToolButton {
                    background: transparent;
                    border: 2px solid #555;
                    border-radius: 35px;
                }
                QToolButton:hover { border-color: #666; }
                QToolButton:pressed { border-color: #777; }
            """)
        else:
            self.setIcon(QIcon(icon_path))
            self.setIconSize(QSize(32, 32))
            self.setStyleSheet("""
                QToolButton {
                    background: #2E2E2E;
                    border: none;
                }
                QToolButton:hover { background: #373737; }
                QToolButton:pressed { background: #404040; }
            """)


class ContactSelector(QListWidget):
    def __init__(self):
        super().__init__()
        self.setStyleSheet("""
            QListWidget {
                background: white;
                border: none;
            }
            QListWidget::item {
                border-bottom: 1px solid #EEE;
                height: 70px;
            }
            QListWidget::item:hover {
                background: #F5F5F5;
            }
            QListWidget::item:selected {
                background: #E5F3FF;
                border-left: 3px solid #0078D4;
            }
        """)
        self.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)


# ========================== 联系人相关组件 ==========================
class SearchResultItem(QWidget):
    def __init__(self, user_data, client, parent=None):
        super().__init__(parent)
        self.client = client
        self.user_data = user_data
        self.init_ui()

    def init_ui(self):
        layout = QHBoxLayout(self)
        layout.setContentsMargins(5, 5, 5, 5)

        # 头像
        avatar_label = QLabel()
        pixmap = QPixmap(self.user_data.get('avatar_path', 'avatar1.jpg'))
        scaled_pixmap = pixmap.scaled(40, 40, Qt.KeepAspectRatio, Qt.SmoothTransformation)
        avatar_label.setPixmap(scaled_pixmap)
        layout.addWidget(avatar_label)

        # 用户信息
        info_layout = QVBoxLayout()
        info_layout.setSpacing(2)

        # 用户名和ID
        name_id_layout = QHBoxLayout()
        username_label = QLabel(self.user_data['username'])
        username_label.setStyleSheet("font-weight: bold;")
        userid_label = QLabel(f"(ID: {self.user_data['user_id']})")
        userid_label.setStyleSheet("color: gray;")
        name_id_layout.addWidget(username_label)
        name_id_layout.addWidget(userid_label)
        name_id_layout.addStretch()
        info_layout.addLayout(name_id_layout)

        # 个性签名
        signature = self.user_data.get('signature', '这个人很懒，什么都没留下')
        signature_label = QLabel(signature)
        signature_label.setStyleSheet("color: gray; font-size: 12px;")
        info_layout.addWidget(signature_label)

        layout.addLayout(info_layout)

        # 添加好友按钮
        add_btn = QPushButton("添加好友")
        add_btn.setFixedWidth(80)
        add_btn.clicked.connect(self.add_friend)
        layout.addWidget(add_btn)

    def add_friend(self):
        try:
            # 发送添加好友请求
            self.client.send_message({
                'type': 'add_friend',
                'user_id': self.client.current_user_id,
                'friend_id': self.user_data['user_id']
            })

            # 禁用添加按钮，防止重复点击
            sender = self.sender()
            if sender:
                sender.setEnabled(False)
                sender.setText("请求已发送")
                sender.setStyleSheet("""
                    QPushButton {
                        background: #ddd;
                        color: #666;
                        border: none;
                        border-radius: 3px;
                        padding: 5px 15px;
                    }
                """)

            QMessageBox.information(self, "提示", "好友请求已发送")

        except Exception as e:
            QMessageBox.warning(self, "错误", f"发送好友请求失败: {str(e)}")


class SearchResultDialog(QDialog):
    def __init__(self, results, client, parent=None):
        super().__init__(parent)
        self.client = client
        self.results = results
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("搜索结果")
        self.setFixedSize(400, 500)

        layout = QVBoxLayout(self)

        # 搜索结果列表
        self.result_list = QListWidget()
        layout.addWidget(self.result_list)

        # 添加搜索结果
        for result in self.results:
            item = QListWidgetItem()
            widget = SearchResultItem(result, self.client)
            item.setSizeHint(widget.sizeHint())
            self.result_list.addItem(item)
            self.result_list.setItemWidget(item, widget)


class FriendRequestItem(QWidget):
    def __init__(self, request_data, client, parent=None):
        super().__init__(parent)
        self.client = client
        self.friend_data = request_data
        self.init_ui()

    def init_ui(self):
        layout = QHBoxLayout(self)
        layout.setContentsMargins(10, 10, 10, 10)
        layout.setSpacing(15)

        # 头像
        avatar_container = QWidget()
        avatar_container.setFixedSize(50, 50)
        avatar_container.setStyleSheet("""
            QWidget {
                background: transparent;
                border-radius: 25px;
            }
        """)
        avatar_layout = QVBoxLayout(avatar_container)
        avatar_layout.setContentsMargins(0, 0, 0, 0)

        avatar_label = QLabel()
        pixmap = QPixmap(self.friend_data.get('avatar_path', 'avatar1.jpg'))
        scaled_pixmap = pixmap.scaled(50, 50, Qt.KeepAspectRatio, Qt.SmoothTransformation)
        avatar_label.setPixmap(scaled_pixmap)
        avatar_label.setStyleSheet("border-radius: 25px;")
        avatar_layout.addWidget(avatar_label)
        layout.addWidget(avatar_container)

        # 用户信息
        info_layout = QVBoxLayout()
        info_layout.setSpacing(5)

        username_label = QLabel(self.friend_data['username'])
        username_label.setStyleSheet("""
            QLabel {
                font-size: 14px;
                font-weight: bold;
                color: #333;
            }
        """)

        userid_label = QLabel(f"ID: {self.friend_data['user_id']}")
        userid_label.setStyleSheet("""
            QLabel {
                font-size: 12px;
                color: #666;
            }
        """)

        info_layout.addWidget(username_label)
        info_layout.addWidget(userid_label)
        layout.addLayout(info_layout)

        # 操作按钮
        btn_layout = QHBoxLayout()
        btn_layout.setSpacing(10)

        accept_btn = QPushButton("接受")
        accept_btn.setFixedSize(70, 30)
        accept_btn.setStyleSheet("""
            QPushButton {
                background-color: #07C160;
                color: white;
                border: none;
                border-radius: 4px;
                font-size: 13px;
            }
            QPushButton:hover {
                background-color: #06B057;
            }
            QPushButton:disabled {
                background-color: #ddd;
                color: #666;
            }
        """)

        reject_btn = QPushButton("拒绝")
        reject_btn.setFixedSize(70, 30)
        reject_btn.setStyleSheet("""
            QPushButton {
                background-color: #FA5151;
                color: white;
                border: none;
                border-radius: 4px;
                font-size: 13px;
            }
            QPushButton:hover {
                background-color: #E64848;
            }
            QPushButton:disabled {
                background-color: #ddd;
                color: #666;
            }
        """)

        accept_btn.clicked.connect(lambda: self.handle_request(True))
        reject_btn.clicked.connect(lambda: self.handle_request(False))

        btn_layout.addWidget(accept_btn)
        btn_layout.addWidget(reject_btn)
        layout.addLayout(btn_layout)

        layout.addStretch()

        # 设置整体样式
        self.setStyleSheet("""
            QWidget {
                background: white;
            }
        """)

    def handle_request(self, accept):
        """处理好友请求"""
        print(f"\n=== 处理好友请求 ===")
        print(f"用户ID: {self.friend_data['user_id']}")
        print(f"操作: {'接受' if accept else '拒绝'}")

        try:
            # 发送处理结果到服务器
            self.client.send_message({
                'type': 'accept_friend',
                'user_id': self.client.current_user_id,
                'friend_id': self.friend_data['user_id'],
                'accept': accept
            })

            # 禁用按钮
            for button in self.findChildren(QPushButton):
                button.setEnabled(False)
                button.setStyleSheet("background-color: #ddd; color: #666;")

            # 显示处理结果
            QMessageBox.information(self, "提示",
                                    "已接受好友请求" if accept else "已拒绝好友请求")

            # 如果接受了好友请求，更新双方的好友列表
            if accept:
                # 更新自己的好友列表
                self.client.send_message({
                    'type': 'get_friends',
                    'user_id': self.client.current_user_id
                })

                # 从好友请求列表中移除该请求
                parent_list = self.parent()
                if isinstance(parent_list, QListWidget):
                    for i in range(parent_list.count()):
                        item = parent_list.item(i)
                        widget = parent_list.itemWidget(item)
                        if widget == self:
                            parent_list.takeItem(i)
                            break

        except Exception as e:
            print(f"处理好友请求失败: {e}")
            QMessageBox.warning(self, "错误", f"处理好友请求失败: {str(e)}")

        print("=== 好友请求处理完成 ===\n")


class FriendItem(QWidget):
    def __init__(self, friend_data, parent=None):
        super().__init__(parent)
        self.friend_data = friend_data
        self.init_ui()

    def init_ui(self):
        layout = QHBoxLayout(self)

        # 头像
        avatar_label = QLabel()
        pixmap = QPixmap(self.friend_data.get('avatar_path', 'avatar1.jpg'))
        scaled_pixmap = pixmap.scaled(40, 40, Qt.KeepAspectRatio, Qt.SmoothTransformation)
        avatar_label.setPixmap(scaled_pixmap)
        layout.addWidget(avatar_label)

        # 用户信息
        info_layout = QVBoxLayout()
        name_label = QLabel(self.friend_data.get('remark', self.friend_data['username']))
        signature_label = QLabel(self.friend_data.get('signature', ''))
        signature_label.setStyleSheet("color: gray;")
        info_layout.addWidget(name_label)
        info_layout.addWidget(signature_label)
        layout.addLayout(info_layout)

        layout.addStretch()


class ContactItem(QWidget):
    def __init__(self, friend_data, parent=None):
        super().__init__(parent)
        self.friend_data = friend_data
        self.setFixedHeight(70)

        layout = QHBoxLayout(self)
        layout.setContentsMargins(15, 10, 15, 10)

        # 头像
        avatar_label = QLabel()
        pixmap = QPixmap(friend_data.get('avatar_path', 'avatar1.jpg'))
        scaled_pixmap = pixmap.scaled(50, 50, Qt.KeepAspectRatio, Qt.SmoothTransformation)
        avatar_label.setPixmap(scaled_pixmap)
        avatar_label.setStyleSheet("border-radius: 25px;")
        layout.addWidget(avatar_label)

        # 用户信息
        info_layout = QVBoxLayout()

        # 用户名
        name_label = QLabel(friend_data.get('username', '未知用户'))
        name_label.setStyleSheet("font: 15px 'Microsoft YaHei';")
        info_layout.addWidget(name_label)

        # 个性签名
        signature_label = QLabel(friend_data.get('signature', '这个人很懒，什么都没留下'))
        signature_label.setStyleSheet("color: #666; font: 12px;")
        info_layout.addWidget(signature_label)

        layout.addLayout(info_layout)
        layout.addStretch()


class ContactsPage(QWidget):
    def __init__(self, client, parent=None):
        super().__init__(parent)
        self.client = client
        self.init_ui()
        self.setup_connections()

    def init_ui(self):
        layout = QVBoxLayout(self)
        layout.setSpacing(10)
        layout.setContentsMargins(20, 20, 20, 20)

        # 搜索区域
        search_layout = QHBoxLayout()
        self.search_input = QLineEdit()
        self.search_input.setPlaceholderText("输入用户ID搜索")
        self.search_input.setStyleSheet("""
            QLineEdit {
                padding: 8px;
                border: 1px solid #ddd;
                border-radius: 4px;
            }
        """)
        self.search_input.returnPressed.connect(self.search_user)
        self.search_btn = QPushButton("搜索")
        self.search_btn.setStyleSheet("""
            QPushButton {
                padding: 8px 15px;
                background: #07C160;
                color: white;
                border: none;
                border-radius: 4px;
            }
            QPushButton:hover {
                background: #06B057;
            }
        """)
        self.search_btn.clicked.connect(self.search_user)
        search_layout.addWidget(self.search_input)
        search_layout.addWidget(self.search_btn)
        layout.addLayout(search_layout)

        # 好友请求区域
        request_container = QWidget()
        request_container.setStyleSheet("""
            QWidget {
                background: white;
                border: 1px solid #eee;
                border-radius: 4px;
            }
        """)
        request_layout = QVBoxLayout(request_container)

        # 好友请求标签
        self.request_label = QLabel("好友请求")
        self.request_label.setStyleSheet("""
            QLabel {
                font-weight: bold;
                font-size: 14px;
                padding: 5px;
                color: #333;
            }
        """)
        request_layout.addWidget(self.request_label)

        # 好友请求列表
        self.request_list = QListWidget()
        self.request_list.setStyleSheet("""
            QListWidget {
                border: none;
                background: transparent;
            }
            QListWidget::item {
                padding: 5px;
                border-bottom: 1px solid #eee;
            }
        """)
        self.request_list.setMaximumHeight(200)
        request_layout.addWidget(self.request_list)
        layout.addWidget(request_container)

        # 好友列表区域
        friends_container = QWidget()
        friends_container.setStyleSheet("""
            QWidget {
                background: white;
                border: 1px solid #eee;
                border-radius: 4px;
            }
        """)
        friends_layout = QVBoxLayout(friends_container)

        # 好友列表标签
        self.friends_label = QLabel("我的好友")
        self.friends_label.setStyleSheet("""
            QLabel {
                font-weight: bold;
                font-size: 14px;
                padding: 5px;
                color: #333;
            }
        """)
        friends_layout.addWidget(self.friends_label)

        # 好友列表
        self.friends_list = QListWidget()
        self.friends_list.setStyleSheet("""
            QListWidget {
                border: none;
                background: transparent;
            }
            QListWidget::item {
                padding: 5px;
                border-bottom: 1px solid #eee;
            }
        """)
        friends_layout.addWidget(self.friends_list)
        layout.addWidget(friends_container)

    def setup_connections(self):
        """设置信号连接"""
        print("\n=== 设置ContactsPage信号连接 ===")

        # 检查并连接搜索结果信号
        if hasattr(self.client, 'search_result_received'):
            print("连接search_result_received信号")
            try:
                self.client.search_result_received.disconnect(self.show_search_results)
            except:
                pass
            self.client.search_result_received.connect(self.show_search_results)
        else:
            print("警告: 客户端没有search_result_received信号")

        # 检查并连接好友列表信号
        if hasattr(self.client, 'friends_received'):
            print("连接friends_received信号")
            try:
                self.client.friends_received.disconnect(self.update_friends_list)
            except:
                pass
            self.client.friends_received.connect(self.update_friends_list)
        else:
            print("警告: 客户端没有friends_received信号")

        # 连接好友请求相关信号
        if hasattr(self.client, 'friend_request_received'):
            print("连接friend_request_received信号")
            try:
                self.client.friend_request_received.disconnect(self.handle_friend_request)
            except:
                pass
            self.client.friend_request_received.connect(self.handle_friend_request)

        if hasattr(self.client, 'friend_request_accepted'):
            print("连接friend_request_accepted信号")
            try:
                self.client.friend_request_accepted.disconnect(self.handle_friend_request_accepted)
            except:
                pass
            self.client.friend_request_accepted.connect(self.handle_friend_request_accepted)

        print("=== 信号连接设置完成 ===\n")

    def handle_friend_request(self, request_data):
        """处理收到的好友请求"""
        print(f"\n=== 处理好友请求 ===")
        print(f"收到好友请求: {request_data}")

        try:
            # 检查是否已存在相同的请求
            for i in range(self.request_list.count()):
                item = self.request_list.item(i)
                widget = self.request_list.itemWidget(item)
                if widget and widget.friend_data['user_id'] == request_data['user_id']:
                    print("该好友请求已存在，不重复添加")
                    return

            # 添加新的好友请求
            item = QListWidgetItem()
            widget = FriendRequestItem(request_data, self.client)
            item.setSizeHint(widget.sizeHint())
            self.request_list.addItem(item)
            self.request_list.setItemWidget(item, widget)
            print("好友请求已添加到列表")

        except Exception as e:
            print(f"处理好友请求时发生错误: {e}")
            import traceback
            print(traceback.format_exc())

        print("=== 好友请求处理完成 ===\n")

    def handle_friend_request_accepted(self, friend_data):
        """处理好友请求被接受的情况"""
        print(f"好友请求被接受: {friend_data}")
        # 刷新好友列表
        if hasattr(self.client, 'current_user_id'):
            self.client.send_message({
                'type': 'get_friends',
                'user_id': self.client.current_user_id
            })

    def search_user(self):
        """搜索用户"""
        keyword = self.search_input.text().strip()
        if not keyword:
            QMessageBox.warning(self, "提示", "请输入用户ID")
            return

        if not keyword.isdigit():
            QMessageBox.warning(self, "提示", "请输入正确的用户ID（纯数字）")
            return

        print(f"\n=== 开始搜索用户 ===")
        print(f"搜索关键词: {keyword}")

        try:
            # 确保客户端已连接
            if not self.client.is_connected:
                print("客户端未连接，尝试重新连接...")
                if not self.client.connect():
                    QMessageBox.warning(self, "连接错误", "无法连接到服务器")
                    return

            # 检查是否已登录
            if not hasattr(self.client, 'current_user_id') or not self.client.current_user_id:
                print("错误：用户未登录")
                QMessageBox.warning(self, "错误", "请先登录")
                return

            # 发送搜索请求
            print(f"发送搜索请求: keyword={keyword}, current_user_id={self.client.current_user_id}")
            success = self.client.send_message({
                'type': 'search',
                'keyword': keyword,
                'current_user_id': self.client.current_user_id
            })

            if not success:
                print("发送搜索请求失败")
                QMessageBox.warning(self, "错误", "发送搜索请求失败")
                return

            print("搜索请求已发送，等待服务器响应...")

        except Exception as e:
            print(f"搜索过程中发生错误: {e}")
            import traceback
            print(traceback.format_exc())
            QMessageBox.warning(self, "错误", f"搜索失败: {str(e)}")

        print("=== 搜索用户结束 ===\n")

    def show_search_results(self, results):
        """显示搜索结果"""
        print(f"\n=== 显示搜索结果 ===")
        print(f"收到搜索结果: {results}")

        try:
            dialog = QDialog(self)
            dialog.setWindowTitle("搜索结果")
            dialog.setFixedSize(400, 500)
            dialog.setStyleSheet("""
                QDialog {
                    background: white;
                }
                QListWidget {
                    border: none;
                }
                QListWidget::item {
                    border-bottom: 1px solid #EEE;
                    padding: 10px;
                }
                QListWidget::item:hover {
                    background: #F5F5F5;
                }
                QPushButton {
                    padding: 5px 15px;
                    background: #07C160;
                    color: white;
                    border: none;
                    border-radius: 3px;
                }
                QPushButton:hover {
                    background: #06B057;
                }
            """)

            layout = QVBoxLayout(dialog)

            if not results:
                print("没有找到搜索结果")
                # 如果没有搜索结果
                no_result_label = QLabel("未找到相关用户")
                no_result_label.setAlignment(Qt.AlignCenter)
                no_result_label.setStyleSheet("color: gray; padding: 20px;")
                layout.addWidget(no_result_label)
            else:
                print(f"找到 {len(results)} 个结果")
                # 搜索结果列表
                result_list = QListWidget()
                layout.addWidget(result_list)

                for result in results:
                    print(f"处理搜索结果: {result}")
                    item = QListWidgetItem()
                    widget = SearchResultItem(result, self.client)
                    item.setSizeHint(widget.sizeHint())
                    result_list.addItem(item)
                    result_list.setItemWidget(item, widget)

            print("显示搜索结果对话框")
            dialog.exec_()

        except Exception as e:
            print(f"显示搜索结果时发生错误: {e}")
            import traceback
            print(traceback.format_exc())
            QMessageBox.warning(self, "错误", f"显示搜索结果失败: {str(e)}")

        print("=== 搜索结果显示完成 ===\n")

    def update_friends_list(self, friends):
        """更新好友列表"""
        print(f"更新好友列表: {friends}")  # 添加调试信息
        self.friends_list.clear()
        for friend in friends:
            item = QListWidgetItem()
            widget = FriendItem(friend)
            item.setSizeHint(widget.sizeHint())
            self.friends_list.addItem(item)
            self.friends_list.setItemWidget(item, widget)

    def update_friend_requests(self, requests):
        """更新好友请求列表"""
        print(f"更新好友请求列表: {requests}")  # 添加调试信息
        self.request_list.clear()
        for request in requests:
            item = QListWidgetItem()
            widget = FriendRequestItem(request, self.client)
            item.setSizeHint(widget.sizeHint())
            self.request_list.addItem(item)
            self.request_list.setItemWidget(item, widget)


# ========================== 主窗口 ==========================
class ChatApp(QMainWindow):
    def __init__(self, client):
        super().__init__()
        self.client = client
        self.current_page = 'chats'  # 当前显示的页面
        self.initUI()
        self.setup_connections()

    def initUI(self):
        self.setWindowTitle("CutyChat")
        self.setWindowIcon(QIcon("kitty.png"))
        self.setGeometry(100, 100, 1200, 800)

        main_widget = QWidget()
        self.setCentralWidget(main_widget)

        layout = QHBoxLayout(main_widget)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)

        # 侧边栏
        self.sidebar = self.buildSidebar()
        layout.addWidget(self.sidebar)

        # 联系人列表面板
        self.contact_panel = ContactSelector()
        layout.addWidget(self.contact_panel, 1)

        # 聊天区域
        self.chat_area = QWidget()
        self.chat_area.setStyleSheet("background: #F0F2F5;")
        layout.addWidget(self.chat_area, 2)

        # 初始化各个页面
        self.chats_page = self.contact_panel
        self.contacts_page = self.build_contacts_page()
        self.favorites_page = self.build_favorites_page()
        self.settings_page = self.build_settings_page()

        # 默认显示会话页面
        self.show_page('chats')

        self.contact_panel.itemClicked.connect(self.showChatWindow)

    def buildSidebar(self):
        sidebar = QWidget()
        sidebar.setFixedWidth(70)
        sidebar.setStyleSheet("background: #2E2E2E;")
        layout = QVBoxLayout(sidebar)
        layout.setContentsMargins(0, 20, 0, 20)
        layout.setSpacing(10)

        # 头像按钮
        avatar_path = getattr(self.client, 'current_avatar_path', 'avatar1.jpg')
        self.avatar_btn = SidebarButton(avatar_path, is_avatar=True)
        self.avatar_btn.clicked.connect(self.show_profile)
        layout.addWidget(self.avatar_btn)

        # 功能按钮
        self.chat_btn = SidebarButton("message.png", "会话")
        self.chat_btn.clicked.connect(lambda: self.show_page('chats'))
        layout.addWidget(self.chat_btn)

        self.contacts_btn = SidebarButton("contact.png", "通讯录")
        self.contacts_btn.clicked.connect(lambda: self.show_page('contacts'))
        layout.addWidget(self.contacts_btn)

        self.favorites_btn = SidebarButton("collect.png", "收藏")
        self.favorites_btn.clicked.connect(lambda: self.show_page('favorites'))
        layout.addWidget(self.favorites_btn)

        self.settings_btn = SidebarButton("settings.png", "设置")
        self.settings_btn.clicked.connect(lambda: self.show_page('settings'))
        layout.addWidget(self.settings_btn)

        layout.addStretch()
        return sidebar

    def show_page(self, page_name):
        """切换显示不同的页面"""
        self.current_page = page_name

        # 隐藏所有页面
        self.chats_page.hide()
        self.contacts_page.hide()
        self.favorites_page.hide()
        self.settings_page.hide()
        self.chat_area.hide()

        # 显示选中的页面
        if page_name == 'chats':
            self.chats_page.show()
            self.chat_area.show()
        elif page_name == 'contacts':
            self.contacts_page.show()
        elif page_name == 'favorites':
            self.favorites_page.show()
        elif page_name == 'settings':
            self.settings_page.show()

    def build_contacts_page(self):
        """构建通讯录页面"""
        return ContactsPage(self.client)

    def build_favorites_page(self):
        """构建收藏页面"""
        page = QWidget()
        layout = QVBoxLayout(page)

        # 收藏列表
        self.favorites_list = QListWidget()
        layout.addWidget(self.favorites_list)

        return page

    def build_settings_page(self):
        """构建设置页面"""
        page = QWidget()
        layout = QVBoxLayout(page)
        layout.setSpacing(20)
        layout.setContentsMargins(30, 30, 30, 30)

        # 设置页面样式
        page.setStyleSheet("""
            QPushButton {
                background-color: white;
                border: 1px solid #ddd;
                border-radius: 4px;
                padding: 10px;
                text-align: left;
                font-size: 14px;
            }
            QPushButton:hover {
                background-color: #f5f5f5;
            }
            QLabel {
                font-size: 16px;
                font-weight: bold;
                color: #333;
                margin-top: 20px;
            }
        """)

        # 个人资料设置
        profile_section = QLabel("个人资料")
        layout.addWidget(profile_section)

        profile_btn = QPushButton("修改个人资料")
        profile_btn.clicked.connect(self.show_profile)
        layout.addWidget(profile_btn)

        # 通用设置
        general_section = QLabel("通用设置")
        layout.addWidget(general_section)

        # 主题设置
        theme_btn = QPushButton("主题设置")
        theme_btn.clicked.connect(self.show_theme_settings)
        layout.addWidget(theme_btn)

        # 消息提醒设置
        notification_btn = QPushButton("消息提醒")
        notification_btn.clicked.connect(self.show_notification_settings)
        layout.addWidget(notification_btn)

        # 隐私设置
        privacy_section = QLabel("隐私设置")
        layout.addWidget(privacy_section)

        privacy_btn = QPushButton("隐私与安全")
        privacy_btn.clicked.connect(self.show_privacy_settings)
        layout.addWidget(privacy_btn)

        # 关于
        about_section = QLabel("关于")
        layout.addWidget(about_section)

        about_btn = QPushButton("关于CutyChat")
        about_btn.clicked.connect(self.show_about_dialog)
        layout.addWidget(about_btn)

        # 添加弹性空间
        layout.addStretch()

        return page

    def show_theme_settings(self):
        """显示主题设置对话框"""
        QMessageBox.information(self, "主题设置", "主题设置功能即将推出，敬请期待！")

    def show_notification_settings(self):
        """显示通知设置对话框"""
        QMessageBox.information(self, "消息提醒设置", "消息提醒设置功能即将推出，敬请期待！")

    def show_privacy_settings(self):
        """显示隐私设置对话框"""
        QMessageBox.information(self, "隐私设置", "隐私设置功能即将推出，敬请期待！")

    def show_about_dialog(self):
        """显示关于对话框"""
        about_text = """
        <h2>CutyChat</h2>
        <p>版本：1.0.0</p>
        <p>一个简洁、可爱的即时通讯软件</p>
        <p>© 2024 CutyChat Team. All rights reserved.</p>
        """
        QMessageBox.about(self, "关于CutyChat", about_text)

    def show_profile(self):
        """显示个人资料对话框"""
        dialog = ProfileDialog(self)
        dialog.exec_()

    def showChatWindow(self, item):
        """显示聊天窗口"""
        print("\n=== 显示聊天窗口 ===")

        try:
            # 获取聊天对象信息
            contact_widget = self.contact_panel.itemWidget(item)
            if not contact_widget:
                print("错误：无法获取联系人信息")
                return

            self.current_chat_contact = {
                'user_id': contact_widget.friend_data['user_id'],
                'username': contact_widget.friend_data['username']
            }
            print(f"当前聊天对象: {self.current_chat_contact}")

            # 清空原有聊天区
            self.chat_area = QWidget()
            self.chat_area.setStyleSheet("background: #F0F2F5;")

            # 构建新聊天窗口
            main_layout = QVBoxLayout(self.chat_area)

            # 聊天头部
            header = QWidget()
            header.setFixedHeight(60)
            header.setStyleSheet("background: white; border-bottom: 1px solid #E6E6E6;")
            header_layout = QHBoxLayout(header)
            title = QLabel(f"{self.current_chat_contact['username']}")
            title.setStyleSheet("font-size: 16px; font-weight: bold;")
            header_layout.addWidget(title)
            main_layout.addWidget(header)

            # 消息显示区域
            self.message_area = QTextBrowser()
            self.message_area.setStyleSheet("""
                QTextBrowser {
                    background: white;
                    border: none;
                    border-radius: 5px;
                    padding: 15px;
                    font: 14px;
                }
            """)
            main_layout.addWidget(self.message_area)

            # 输入区域
            input_box = QTextEdit()
            input_box.setPlaceholderText("输入消息...")
            input_box.setStyleSheet("""
                QTextEdit {
                    background: white;
                    border: none;
                    border-radius: 5px;
                    padding: 15px;
                    font: 14px;
                    min-height: 80px;
                }
            """)

            # 发送按钮
            send_btn = QPushButton("发送")
            send_btn.setFixedSize(80, 35)
            send_btn.setStyleSheet("""
                QPushButton {
                    background: #0078D4;
                    color: white;
                    border-radius: 4px;
                    font: bold 14px;
                }
                QPushButton:hover {
                    background: #006CBC;
                }
            """)

            # 绑定发送消息的槽函数
            send_btn.clicked.connect(lambda: self.send_message(input_box.toPlainText()))

            # 输入区域布局
            input_layout = QHBoxLayout()
            input_layout.addWidget(input_box)
            input_layout.addWidget(send_btn)
            main_layout.addLayout(input_layout)

            # 更新界面
            layout = self.centralWidget().layout()
            layout.replaceWidget(layout.itemAt(2).widget(), self.chat_area)

            print("聊天窗口显示完成")

        except Exception as e:
            print(f"显示聊天窗口时发生错误: {e}")
            import traceback
            print(traceback.format_exc())
            QMessageBox.warning(self, "错误", f"无法显示聊天窗口: {str(e)}")

    def send_message(self, message):
        """发送消息"""
        print("\n=== 发送消息 ===")

        if not message.strip():
            print("消息内容为空，不发送")
            return

        try:
            print(f"准备发送消息给 {self.current_chat_contact['username']}")
            success = self.client.send_message({
                'type': 'message',
                'from': self.client.current_user_id,
                'to': self.current_chat_contact['user_id'],
                'content': message
            })

            if success:
                print("消息发送成功")
                # 在自己的聊天窗口显示消息
                self.message_area.append(f"[我]: {message}")
                # 清空输入框
                input_box = self.chat_area.layout().itemAt(2).layout().itemAt(0).widget()
                input_box.clear()
            else:
                print("消息发送失败")
                QMessageBox.warning(self, "发送失败", "无法发送消息，请检查网络连接")

        except Exception as e:
            print(f"发送消息时发生错误: {e}")
            import traceback
            print(traceback.format_exc())
            QMessageBox.warning(self, "错误", f"发送消息失败: {str(e)}")

        print("=== 消息发送完成 ===\n")

    def handle_new_message(self, message):
        """处理新消息"""
        print("\n=== 处理新消息 ===")
        print(f"收到消息: {message}")

        try:
            content = message.get('content')
            sender_id = message.get('from')

            if content and sender_id:
                # 获取发送者用户名
                sender_name = "未知用户"
                for item in range(self.contact_panel.count()):
                    contact_widget = self.contact_panel.itemWidget(self.contact_panel.item(item))
                    if contact_widget and contact_widget.friend_data['user_id'] == sender_id:
                        sender_name = contact_widget.friend_data['username']
                        break

                # 如果当前正在与发送者聊天，则在聊天窗口显示消息
                if (hasattr(self, 'current_chat_contact') and
                        self.current_chat_contact['user_id'] == sender_id):
                    self.message_area.append(f"[{sender_name}]: {content}")
                else:
                    # 否则显示消息通知
                    QMessageBox.information(self, "新消息",
                                            f"收到来自 {sender_name} 的新消息：\n{content}")

        except Exception as e:
            print(f"处理新消息时发生错误: {e}")
            import traceback
            print(traceback.format_exc())

        print("=== 新消息处理完成 ===\n")

    def setup_connections(self):
        self.client.message_received.connect(self.handle_new_message)
        self.client.friends_received.connect(self.update_contacts)
        self.client.search_result_received.connect(self.show_search_results)

    def update_contacts(self, contacts):
        self.contact_panel.clear()
        for contact in contacts:
            item = QListWidgetItem()
            widget = ContactItem(contact)
            self.contact_panel.addItem(item)
            self.contact_panel.setItemWidget(item, widget)

    def show_search_results(self, results):
        search_results_dialog = QDialog(self)
        search_results_dialog.setWindowTitle("搜索结果")
        search_results_dialog.setFixedSize(600, 400)

        layout = QVBoxLayout(search_results_dialog)

        results_list = QListWidget()
        results_list.setStyleSheet("""
            QListWidget {
                background: white;
                border: none;
            }
            QListWidget::item {
                border-bottom: 1px solid #EEE;
                height: 50px;
            }
            QListWidget::item:hover {
                background: #F5F5F5;
            }
            QListWidget::item:selected {
                background: #E5F3FF;
            }
        """)
        for result in results:
            item = QListWidgetItem()
            results_list.addItem(item)
            results_list.setItemWidget(item, ContactItem(result))

        layout.addWidget(results_list)

        search_results_dialog.exec_()

    def search_user(self, keyword):
        """搜索用户"""
        if keyword:
            self.client.send_message({
                'type': 'search',
                'keyword': keyword
            })


# ========================== 登录窗口 ==========================
class LoginWindow(QDialog):
    def __init__(self, client):
        super().__init__()
        self.client = client
        self.is_logging_in = False  # 添加登录状态标志
        self.setWindowTitle("登录")
        self.setWindowIcon(QIcon("kitty.png"))
        self.resize(800, 600)
        self.init_ui()

        # 移除在初始化时的连接尝试
        # 将在实际登录时进行连接

    def init_ui(self):
        self.setWindowTitle('登录 - CutyChat')
        self.setWindowIcon(QIcon("kitty.png"))
        self.setFixedSize(500, 500)
        # 设置窗口标志，添加最小化按钮
        self.setWindowFlags(Qt.Window | Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint)
        self.setStyleSheet("""
            QDialog {
                background-color: white;
            }
            QLineEdit {
                padding: 10px;
                border: 1px solid #ddd;
                border-radius: 5px;
                font-size: 14px;
            }
            QPushButton {
                padding: 10px;
                border-radius: 5px;
                font-size: 14px;
                color: white;
                background-color: #07C160;
            }
            QPushButton:hover {
                background-color: #06B057;
            }
            QPushButton#linkButton {
                background: none;
                border: none;
                color: #07C160;
                text-decoration: underline;
            }
            QPushButton#linkButton:hover {
                color: #06B057;
            }
            QLabel {
                font-size: 14px;
            }
        """)

        layout = QVBoxLayout()
        layout.setSpacing(15)
        layout.setContentsMargins(40, 40, 40, 40)

        # Logo
        logo_label = QLabel()
        logo_pixmap = QPixmap("kitty.png").scaled(100, 100, Qt.KeepAspectRatio, Qt.SmoothTransformation)
        logo_label.setPixmap(logo_pixmap)
        layout.addWidget(logo_label, alignment=Qt.AlignCenter)

        # 标题
        title = QLabel("CutyChat")
        title.setFont(QFont("微软雅黑", 24, QFont.Bold))
        title.setAlignment(Qt.AlignCenter)
        layout.addWidget(title)

        # 用户ID输入
        self.user_id_input = QLineEdit()
        self.user_id_input.setPlaceholderText("用户ID")
        layout.addWidget(self.user_id_input)

        # 密码输入
        self.password_input = QLineEdit()
        self.password_input.setPlaceholderText("密码")
        self.password_input.setEchoMode(QLineEdit.Password)
        layout.addWidget(self.password_input)

        # 登录按钮
        login_btn = QPushButton("登录")
        login_btn.clicked.connect(self.handle_login)
        layout.addWidget(login_btn)

        # 辅助按钮容器
        helper_layout = QHBoxLayout()

        # 注册按钮
        register_btn = QPushButton("注册账号")
        register_btn.setObjectName("linkButton")
        register_btn.clicked.connect(self.show_register_dialog)
        helper_layout.addWidget(register_btn)

        # 忘记密码按钮
        forget_pwd_btn = QPushButton("忘记密码")
        forget_pwd_btn.setObjectName("linkButton")
        forget_pwd_btn.clicked.connect(self.show_forget_password_dialog)
        helper_layout.addWidget(forget_pwd_btn)

        layout.addLayout(helper_layout)
        self.setLayout(layout)

    def show_register_dialog(self):
        dialog = QDialog(self)
        dialog.setWindowTitle("注册新账号")
        dialog.setFixedSize(350, 400)
        dialog.setStyleSheet(self.styleSheet())

        layout = QVBoxLayout()
        layout.setSpacing(15)
        layout.setContentsMargins(30, 30, 30, 30)

        # 用户ID输入
        user_id_input = QLineEdit()
        user_id_input.setPlaceholderText("设置用户ID（仅数字）")
        layout.addWidget(user_id_input)

        # 用户名输入
        username_input = QLineEdit()
        username_input.setPlaceholderText("设置用户名")
        layout.addWidget(username_input)

        # 密码输入
        password_input = QLineEdit()
        password_input.setPlaceholderText("设置密码")
        password_input.setEchoMode(QLineEdit.Password)
        layout.addWidget(password_input)

        # 确认密码
        confirm_password_input = QLineEdit()
        confirm_password_input.setPlaceholderText("确认密码")
        confirm_password_input.setEchoMode(QLineEdit.Password)
        layout.addWidget(confirm_password_input)

        # 注册按钮
        register_btn = QPushButton("注册")
        register_btn.clicked.connect(lambda: self.register(
            user_id_input.text(),
            username_input.text(),
            password_input.text(),
            confirm_password_input.text()
        ))
        layout.addWidget(register_btn)

        dialog.setLayout(layout)
        dialog.exec_()

    def register(self, user_id, username, password, confirm_password):
        if not user_id or not username or not password or not confirm_password:
            QMessageBox.warning(self, "提示", "所有字段都必须填写")
            return
        if not user_id.isdigit():
            QMessageBox.warning(self, "提示", "用户ID必须是数字")
            return
        if password != confirm_password:
            QMessageBox.warning(self, "提示", "两次输入的密码不一致")
            return

        # 发送注册请求到服务器
        self.client.send_message({
            'type': 'register',
            'user_id': int(user_id),
            'username': username,
            'password': password
        })

    def show_forget_password_dialog(self):
        dialog = QDialog(self)
        dialog.setWindowTitle("找回密码")
        dialog.setFixedSize(350, 200)
        dialog.setStyleSheet(self.styleSheet())

        layout = QVBoxLayout()
        layout.setSpacing(15)
        layout.setContentsMargins(30, 30, 30, 30)

        # 用户ID输入
        user_id_input = QLineEdit()
        user_id_input.setPlaceholderText("请输入您的用户ID")
        layout.addWidget(user_id_input)

        # 找回密码按钮
        recover_btn = QPushButton("找回密码")
        recover_btn.clicked.connect(lambda: self.recover_password(user_id_input.text()))
        layout.addWidget(recover_btn)

        dialog.setLayout(layout)
        dialog.exec_()

    def recover_password(self, user_id):
        if not user_id:
            QMessageBox.warning(self, "提示", "请输入用户ID")
            return
        if not user_id.isdigit():
            QMessageBox.warning(self, "提示", "用户ID必须是数字")
            return

        # 发送找回密码请求到服务器
        self.client.send_message({
            'type': 'recover_password',
            'user_id': int(user_id)
        })

    def handle_login(self):
        """处理登录请求"""
        if self.is_logging_in:  # 如果正在登录中，直接返回
            print("登录请求正在处理中，请等待...")
            return

        user_id = self.user_id_input.text()
        password = self.password_input.text()

        if not user_id or not password:
            QMessageBox.warning(self, "提示", "用户ID和密码不能为空")
            return
        if not user_id.isdigit():
            QMessageBox.warning(self, "提示", "用户ID必须是数字")
            return

        self.is_logging_in = True  # 设置登录状态
        print(f"准备发送登录请求 - 用户ID: {user_id}")

        # 在这里进行连接
        if not self.client.is_connected:
            print("尝试连接到服务器...")
            if not self.client.connect():
                self.is_logging_in = False
                QMessageBox.warning(self, "连接错误", "无法连接到服务器")
                return
            print("已连接到服务器")
            self.client.start_receive_thread()
            print("已启动接收消息线程")

        # 发送登录请求到服务器
        login_success = self.client.send_message({
            'type': 'login',
            'user_id': int(user_id),
            'password': password
        })

        if not login_success:
            self.is_logging_in = False
            QMessageBox.warning(self, "发送失败", "无法发送登录请求")
            self.client.disconnect()  # 断开连接
            return

        print("登录请求已发送，等待服务器响应...")

    def closeEvent(self, event):
        """窗口关闭时的处理"""
        if self.client.is_connected:
            self.client.disconnect()  # 断开连接
        super().closeEvent(event)


# ========================== 网络通信模块 ==========================
class SocketClient(QObject):
    login_success = pyqtSignal()
    message_received = pyqtSignal(dict)
    friends_received = pyqtSignal(list)
    search_result_received = pyqtSignal(list)
    profile_updated = pyqtSignal(dict)
    register_response_received = pyqtSignal(dict)
    recover_password_response_received = pyqtSignal(dict)
    friend_request_received = pyqtSignal(dict)  # 新增：收到好友请求的信号
    friend_request_accepted = pyqtSignal(dict)  # 新增：好友请求被接受的信号
    message_ready = pyqtSignal(dict)

    def __init__(self):
        super().__init__()
        self.socket = None
        self.is_connected = False
        self.should_stop = False
        self.current_user_id = None
        self.current_username = None
        self.current_avatar_path = None
        self.current_signature = None
        self.current_email = None
        self.current_phone = None
        self.current_gender = None
        self.current_birthday = None
        self.receive_thread = None

        # 连接信号到处理函数
        self.message_ready.connect(self.handle_message)

    def create_socket(self):
        """创建新的套接字"""
        if self.socket:
            try:
                self.socket.close()
            except:
                pass
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.settimeout(1)  # 设置更短的超时时间，便于及时响应

    def connect(self):
        """连接到服务器"""
        try:
            self.should_stop = False
            self.create_socket()
            self.socket.connect(('localhost', 8888))
            self.is_connected = True
            print("成功连接到服务器")
            return True
        except Exception as e:
            print(f"连接服务器失败: {e}")
            self.is_connected = False
            return False

    def disconnect(self):
        """断开连接"""
        print("正在断开连接...")
        self.should_stop = True
        self.is_connected = False
        if self.socket:
            try:
                self.socket.close()
                print("套接字已关闭")
            except:
                pass
        self.socket = None
        if self.receive_thread:
            try:
                self.receive_thread.join(timeout=1)  # 等待接收线程结束
                print("接收线程已结束")
            except:
                pass
        print("连接已断开")

    def start_receive_thread(self):
        """启动接收消息的线程"""
        print("准备启动接收消息线程")
        self.receive_thread = threading.Thread(target=self.receive_messages)
        self.receive_thread.daemon = True
        self.receive_thread.start()
        print("接收消息线程已启动")

    def receive_messages(self):
        """接收消息"""
        print("\n=== 开始接收消息循环 ===")
        buffer = ""
        while not self.should_stop and self.is_connected:
            try:
                if not self.socket:
                    print("套接字已关闭，退出接收循环")
                    break

                print("等待接收数据...")
                try:
                    data = self.socket.recv(4096)
                    if not data:
                        print("接收到空数据，连接可能已断开")
                        break

                    buffer += data.decode()
                    print(f"接收到数据: {buffer}")

                    try:
                        # 尝试解析JSON
                        message = json.loads(buffer)
                        buffer = ""  # 清空缓冲区
                        print(f"解析后的消息: {message}")
                        # 使用信号发送消息到主线程
                        self.message_ready.emit(message)
                    except json.JSONDecodeError:
                        # 如果解析失败，可能是数据不完整，继续接收
                        continue

                except socket.timeout:
                    continue  # 超时后继续循环

            except Exception as e:
                print(f"接收消息时发生错误: {e}")
                if not self.should_stop:  # 如果不是主动停止，尝试重新连接
                    print("尝试重新连接...")
                    if self.reconnect():
                        continue
                break

        print("退出接收消息循环")
        if not self.should_stop:  # 如果不是主动停止，说明出现了错误
            self.is_connected = False
            if self.socket:
                try:
                    self.socket.close()
                except:
                    pass
            self.socket = None

    def handle_message(self, message):
        """处理接收到的消息"""
        msg_type = message.get('type')
        print(f"\n=== 处理消息 ===")
        print(f"消息类型: {msg_type}")
        print(f"完整消息: {message}")

        try:
            if msg_type == 'login_response':
                print("\n=== 处理登录响应 ===")
                if message.get('status') == 'success':
                    print("1. 登录成功，开始更新用户信息")
                    self.current_user_id = message.get('user_id')
                    self.current_username = message.get('username')
                    self.current_avatar_path = message.get('avatar_path', 'avatar1.jpg')
                    self.current_signature = message.get('signature', '这个人很懒，什么都没留下')
                    self.current_email = message.get('email', '')
                    self.current_phone = message.get('phone', '')
                    self.current_gender = message.get('gender', '未设置')
                    self.current_birthday = message.get('birthday', '')
                    print("2. 用户信息更新完成")

                    # 发送登录成功信号（先发送，以便创建UI）
                    print("3. 发送登录成功信号")
                    self.login_success.emit()
                    print("4. 登录成功信号已发送")

                    # 处理好友列表
                    friends = message.get('friends', [])
                    if friends:
                        print("5. 发送好友列表更新")
                        self.friends_received.emit(friends)

                    # 处理好友请求列表
                    friend_requests = message.get('friend_requests', [])
                    if friend_requests:
                        print("6. 处理待处理的好友请求")
                        for request in friend_requests:
                            print(f"发送好友请求通知: {request}")
                            self.friend_request_received.emit(request)

                else:
                    print(f"登录失败: {message.get('message', '未知错误')}")
                    QMessageBox.warning(None, "登录失败", message.get('message', '未知错误'))

            elif msg_type == 'message':
                self.message_received.emit(message)
            elif msg_type == 'search_result':
                print(f"收到搜索结果: {message.get('data', [])}")
                self.search_result_received.emit(message.get('data', []))
            elif msg_type == 'friends_list':
                print(f"收到好友列表: {message.get('friends', [])}")
                self.friends_received.emit(message.get('friends', []))
            elif msg_type == 'update_profile_response':
                if message.get('status') == 'success':
                    self.profile_updated.emit(message.get('updates', {}))
            elif msg_type == 'add_friend_response':
                status = message.get('status')
                msg = message.get('message', '')
                if status == 'success':
                    QMessageBox.information(None, "添加好友", msg)
                else:
                    QMessageBox.warning(None, "添加好友失败", msg)
            elif msg_type == 'friend_request':
                # 收到好友请求
                print("收到新的好友请求")
                request_data = {
                    'user_id': message.get('from_user_id'),
                    'username': message.get('from_username'),
                    'avatar_path': message.get('avatar_path', 'avatar1.jpg')
                }
                self.friend_request_received.emit(request_data)
                QMessageBox.information(None, "新的好友请求",
                                        f"用户 {request_data['username']}(ID: {request_data['user_id']}) 请求添加您为好友")
            elif msg_type == 'friend_accepted':
                # 好友请求被接受
                print("好友请求被接受")
                friend_data = {
                    'user_id': message.get('friend_id'),
                    'username': message.get('friend_username', ''),
                    'avatar_path': message.get('avatar_path', 'avatar1.jpg')
                }
                self.friend_request_accepted.emit(friend_data)
                QMessageBox.information(None, "好友请求已接受",
                                        f"用户 {friend_data['username']}(ID: {friend_data['user_id']}) 已接受您的好友请求")
            else:
                print(f"未知的消息类型: {msg_type}")
        except Exception as e:
            print(f"处理消息时发生错误: {e}")
            import traceback
            print(traceback.format_exc())

        print("=== 消息处理完成 ===\n")

    def reconnect(self):
        """重新连接到服务器"""
        print("\n=== 尝试重新连接 ===")
        max_attempts = 3
        attempt = 0

        while attempt < max_attempts and not self.is_connected:
            attempt += 1
            print(f"重连尝试 {attempt}/{max_attempts}")

            try:
                self.create_socket()
                self.socket.connect(('localhost', 8888))
                self.is_connected = True
                print("重连成功")

                # 重新启动接收线程
                if not self.receive_thread or not self.receive_thread.is_alive():
                    print("重新启动接收线程")
                    self.start_receive_thread()

                return True
            except Exception as e:
                print(f"重连失败: {e}")
                if self.socket:
                    try:
                        self.socket.close()
                    except:
                        pass
                    self.socket = None
                if attempt < max_attempts:
                    print("等待1秒后重试...")
                    import time
                    time.sleep(1)

        print("重连失败，已达到最大重试次数")
        return False

    def send_message(self, data):
        """发送消息"""
        print("\n=== 发送消息 ===")
        max_attempts = 3
        attempt = 0

        while attempt < max_attempts:
            attempt += 1
            print(f"发送尝试 {attempt}/{max_attempts}")

            if not self.is_connected or not self.socket:
                print("未连接，尝试重新连接")
                if not self.reconnect():
                    if attempt >= max_attempts:
                        print("无法连接到服务器")
                        QMessageBox.warning(None, "连接错误", "无法连接到服务器")
                        return False
                    continue

            try:
                print(f"准备发送消息: {data}")
                message = json.dumps(data).encode()
                self.socket.sendall(message)
                print("消息发送成功")
                return True
            except Exception as e:
                print(f"发送消息错误: {e}")
                self.is_connected = False
                if self.socket:
                    try:
                        self.socket.close()
                    except:
                        pass
                    self.socket = None
                if attempt >= max_attempts:
                    print("发送失败，已达到最大重试次数")
                    QMessageBox.warning(None, "发送失败", "无法连接到服务器")
                    return False
                print("等待1秒后重试...")
                import time
                time.sleep(1)

        return False


# ========================== 程序入口 ==========================
if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setFont(QFont("Microsoft YaHei", 10))

    client = SocketClient()
    login_window = LoginWindow(client)
    main_window = None  # 声明主窗口变量


    def on_login_success():
        """登录成功的处理函数"""
        try:
            print("\n=== 登录成功回调开始 ===")
            print("1. 准备关闭登录窗口")
            login_window.is_logging_in = False  # 重置登录状态
            login_window.accept()
            print("2. 登录窗口已关闭")

            print("3. 准备创建主窗口")
            global main_window  # 声明使用全局变量
            main_window = ChatApp(client)
            print("4. 主窗口创建成功")

            print("5. 准备显示主窗口")
            main_window.show()
            print("6. 主窗口显示成功")
            print("=== 登录成功回调结束 ===\n")

        except Exception as e:
            print("\n!!! 显示主窗口时出错 !!!")
            print(f"错误类型: {type(e).__name__}")
            print(f"错误信息: {str(e)}")
            import traceback
            print("\n详细错误信息:")
            print(traceback.format_exc())
            QMessageBox.critical(None, "错误", f"无法显示主窗口: {str(e)}")
            app.quit()


    # 确保信号连接在主线程中进行
    print("\n=== 程序启动 ===")
    print("1. 创建信号连接")
    client.login_success.connect(on_login_success)
    print("2. 登录成功信号连接完成")

    print("3. 显示登录窗口")
    result = login_window.exec_()
    print(f"4. 登录窗口返回结果: {result}")

    if result == QDialog.Accepted:
        print("5. 登录成功，进入主事件循环")
        sys.exit(app.exec_())
    else:
        print("5. 用户取消登录，退出程序")
        client.disconnect()  # 确保断开连接
        app.quit()


class ProfileDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.client = parent.client if parent else None
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("个人资料")
        self.setFixedSize(400, 600)
        self.setStyleSheet("""
            QDialog {
                background: white;
            }
            QLabel {
                font-size: 14px;
            }
            QLineEdit {
                padding: 8px;
                border: 1px solid #ddd;
                border-radius: 4px;
                font-size: 14px;
            }
            QPushButton {
                padding: 8px;
                border-radius: 4px;
                font-size: 14px;
                color: white;
                background: #07C160;
            }
            QPushButton:hover {
                background: #06B057;
            }
            QPushButton#avatarBtn {
                background: transparent;
                border: 2px solid #ddd;
                border-radius: 50px;
            }
            QPushButton#avatarBtn:hover {
                border-color: #07C160;
            }
        """)

        layout = QVBoxLayout(self)
        layout.setSpacing(20)
        layout.setContentsMargins(30, 30, 30, 30)

        # 头像
        avatar_layout = QHBoxLayout()
        avatar_label = QLabel("头像")
        self.avatar_btn = QPushButton()
        self.avatar_btn.setObjectName("avatarBtn")
        self.avatar_btn.setFixedSize(100, 100)
        self.avatar_btn.setIconSize(QSize(90, 90))
        current_avatar = self.client.current_avatar_path if hasattr(self.client,
                                                                    'current_avatar_path') else 'avatar1.jpg'
        self.avatar_btn.setIcon(QIcon(current_avatar))
        self.avatar_btn.clicked.connect(self.change_avatar)
        avatar_layout.addWidget(avatar_label)
        avatar_layout.addWidget(self.avatar_btn)
        avatar_layout.addStretch()
        layout.addLayout(avatar_layout)

        # 用户ID（只读）
        userid_layout = QHBoxLayout()
        userid_label = QLabel("用户ID")
        self.userid_input = QLineEdit(str(self.client.current_user_id))
        self.userid_input.setReadOnly(True)
        userid_layout.addWidget(userid_label)
        userid_layout.addWidget(self.userid_input)
        layout.addLayout(userid_layout)

        # 用户名
        username_layout = QHBoxLayout()
        username_label = QLabel("用户名")
        self.username_input = QLineEdit(
            self.client.current_username if hasattr(self.client, 'current_username') else '')
        username_layout.addWidget(username_label)
        username_layout.addWidget(self.username_input)
        layout.addLayout(username_layout)

        # 个性签名
        signature_layout = QHBoxLayout()
        signature_label = QLabel("个性签名")
        self.signature_input = QLineEdit(
            self.client.current_signature if hasattr(self.client, 'current_signature') else '这个人很懒，什么都没留下'
        )
        signature_layout.addWidget(signature_label)
        signature_layout.addWidget(self.signature_input)
        layout.addLayout(signature_layout)

        # 性别
        gender_layout = QHBoxLayout()
        gender_label = QLabel("性别")
        self.gender_input = QLineEdit(
            self.client.current_gender if hasattr(self.client, 'current_gender') else '未设置'
        )
        gender_layout.addWidget(gender_label)
        gender_layout.addWidget(self.gender_input)
        layout.addLayout(gender_layout)

        # 生日
        birthday_layout = QHBoxLayout()
        birthday_label = QLabel("生日")
        self.birthday_input = QLineEdit(
            self.client.current_birthday if hasattr(self.client, 'current_birthday') else ''
        )
        self.birthday_input.setPlaceholderText("格式：YYYY-MM-DD")
        birthday_layout.addWidget(birthday_label)
        birthday_layout.addWidget(self.birthday_input)
        layout.addLayout(birthday_layout)

        # 邮箱
        email_layout = QHBoxLayout()
        email_label = QLabel("邮箱")
        self.email_input = QLineEdit(
            self.client.current_email if hasattr(self.client, 'current_email') else ''
        )
        email_layout.addWidget(email_label)
        email_layout.addWidget(self.email_input)
        layout.addLayout(email_layout)

        # 手机号
        phone_layout = QHBoxLayout()
        phone_label = QLabel("手机号")
        self.phone_input = QLineEdit(
            self.client.current_phone if hasattr(self.client, 'current_phone') else ''
        )
        phone_layout.addWidget(phone_label)
        phone_layout.addWidget(self.phone_input)
        layout.addLayout(phone_layout)

        # 保存按钮
        save_btn = QPushButton("保存")
        save_btn.clicked.connect(self.save_profile)
        layout.addWidget(save_btn)

    def change_avatar(self):
        """更换头像"""
        file_name, _ = QFileDialog.getOpenFileName(
            self, "选择头像", "", "图片文件 (*.jpg *.png)"
        )
        if file_name:
            pixmap = QPixmap(file_name)
            scaled_pixmap = pixmap.scaled(90, 90, Qt.KeepAspectRatio, Qt.SmoothTransformation)
            self.avatar_btn.setIcon(QIcon(scaled_pixmap))
            self.new_avatar_path = file_name

    def save_profile(self):
        """保存个人资料"""
        updates = {
            'username': self.username_input.text(),
            'signature': self.signature_input.text(),
            'gender': self.gender_input.text(),
            'birthday': self.birthday_input.text(),
            'email': self.email_input.text(),
            'phone': self.phone_input.text()
        }

        if hasattr(self, 'new_avatar_path'):
            updates['avatar_path'] = self.new_avatar_path

        self.client.send_message({
            'type': 'update_profile',
            'user_id': self.client.current_user_id,
            'updates': updates
        })

        # 更新客户端的当前用户信息
        for key, value in updates.items():
            setattr(self.client, f'current_{key}', value)

        QMessageBox.information(self, "提示", "个人资料已更新")
        self.accept()
